#ifndef MERGER_H_
#define MERGER_H_

#include <stdexcept>
#include <vector>
#include <fstream>
#include "../utils/PalabraAleatoria.h"


class Merger {
	private:
		int _cantArchivosExistentes;
		int _ordenParticionInit;
		std::string _carpetaParticiones;

		std::ofstream fout;
		std::vector<std::ifstream*> _vecArchEntrada;

		void descargarArchivos();
		void cargarArchivos(int cantArch, int etapa);
		void fusionarArchivos(int nroFusion, int etapa);

		// Señala si todavia existen terminos a leer en las particiones
		bool existenTerminos(std::vector<PalabraAleatoria> &terminos) const;

		// Actualiza el vector de terminos leyendo del archivo que correspode
		void leerTerminos(std::vector<PalabraAleatoria> &terminos, PalabraAleatoria termAnterior);
		void leerTerminos(std::vector<PalabraAleatoria> &terminos);

		// Devuelve la menor palabra aleatoria del vector de palabras
		PalabraAleatoria getTerminoMinimo(std::vector<PalabraAleatoria> &terminos) const;

		int calcularCantEtapas(int nivelMerge, int cantTotalArchivos) const;

		// Copia el resultado a la raiz donde se encuentra el programa
		std::string moverArchResultado(int etapa, bool incluirOrden) const;

	public:
		Merger(const int cantParticiones, std::string carpetaParticiones);
		virtual ~Merger();

		/* Fusiona "fusionesSimultaneas" cantidad de particiones a la vez
		 * y devuelve el nombre del archivo final
		 * "incluirOrden" indica si el archivo final debe contener los identificadores de orden
		 */
		std::string fusionarParticiones(int fusionesSimultaneas, bool incluirOrden = true);
};

#endif /* MERGER_H_ */
